/*
 * @描述: 
 * @创建者: kilomChou
 * @Date: 2021-05-14 21:33:36
 * @最后编辑: kilomChou
 * @LastEditTime: 2021-05-15 16:01:01
 */

import { IRect, ISize, Vec2 } from "../../core/vec2/Vec2";
import Snake from "../snake/Snake";
import SnakeNode from "../snake/SnakeNode";
import Chunk from "../world/Chunk";
import Food from "../world/Food";
import World from "../world/World";
const [v2] = [Vec2];

/** 玩家 */
export default class Player {

    constructor(
        /** 所在世界 */
        readonly world: World,
        name: string
    ) {
        this.snake = world.snakeMgr.createSnake(name, false);
    }

    /** 屏幕宽高 */
    screenSize: ISize = { w: 800, h: 600 };
    /** 屏幕（可见范围） */
    screen: IRect = { x: 0, y: 0, ...this.screenSize };
    /** 屏幕区块 */
    screenChunks: Chunk[];
    /** 蛇 */
    snake: Snake;

    /** 唯一标识(与蛇id对应) */
    get id() { return this.snake.id; }
    /** 玩家名称(与蛇名称对应) */
    get name() { return this.snake.name; }

    /** 控制角度 */
    ctrlTurn(ang: number) {
        if (!this.snake.isDeath)
            this.snake.toAng = ang;
    }

    /** 控制加速 */
    ctrlSprint(isSprint: boolean) {
        if (!this.snake.isDeath)
            this.snake.isSprint = isSprint;
    }

    /** 更新屏幕 */
    updateScreen() {
        if (!this.snake.isDeath) {
            v2.posAs(this.screen, this.snake.head);
        }
        v2.sizeAs(this.screen, this.screenSize);
    }

    /** 更新屏幕区块 */
    updateScreenChunks() {
        this.updateScreen();
        this.screenChunks = this.world.getChunks(this.screen, false);
    }

    /** 更新可见食物映射 */
    updateScreenFoodMap(foodSet: Set<number>): {
        /** 加载食物集合 */
        loadFoods: Food[],
        /** 卸载食物集合 */
        unloadFoodMap: Map<number, number>
    } {
        this.updateScreenChunks();

        let loadFoods: Food[] = []
        //<食物id,吃食物的蛇节点id>
        let unloadFoodMap = new Map<number, number>()
        foodSet.forEach(foodId => unloadFoodMap.set(foodId, 0))

        this.world.getFoods(this.screenChunks).forEach(food => {
            //从卸载集合中移除 剩下的就是待卸载的
            unloadFoodMap.delete(food.id)
            if (!foodSet.has(food.id)) {
                //待加载的
                loadFoods.push(food)
                foodSet.add(food.id)
            }
        })
        let eatenFoodMap = this.world.extractEatenFoodMap()
        unloadFoodMap.forEach((_, foodId) => {
            foodSet.delete(foodId)
            let eaterId = eatenFoodMap.get(foodId)
            if (eaterId) {
                unloadFoodMap.set(foodId, eaterId)
            }
        })

        return { loadFoods, unloadFoodMap }
    }

    /** 更新可见蛇节点映射 */
    updateScreenNodeMap(nodeSet: Set<number>): {
        /** 加载蛇节点映射 <蛇节点id,蛇节点> */
        loadNodeMap: Map<Snake, SnakeNode[]>,
        /** 卸载蛇节点集合 */
        unloadNodeIdSet: Set<number>
    } {
        this.updateScreenChunks()

        let loadNodeMap = this.world.getSnakeNodeMap(this.screenChunks);
        let unloadNodeIdSet = new Set(nodeSet)

        loadNodeMap.forEach(nodes => {
            nodes.forEach(node => {
                //从已有中去除，剩下的就是待卸载的
                unloadNodeIdSet.delete(node.id)
                //待加载的
                nodeSet.add(node.id)
            })
        })
        unloadNodeIdSet.forEach(nodeId => nodeSet.delete(nodeId))

        return { loadNodeMap, unloadNodeIdSet }
    }

    /** 更新已加载蛇映射 */
    updateLoadedSnakeMap(snakeSet: Set<number>): {
        /** 加载蛇集合 */
        loadSnakes: Snake[],
        /** 卸载蛇集合 */
        unloadSnakeIdSet: Set<number>
    } {
        let loadSnakes: Snake[] = []
        let unloadSnakeIdSet = new Set(snakeSet)

        this.world.snakeMgr.snakeMap.forEach((snake, snakeId) => {
            //从已有中去除，剩下的就是待卸载的
            unloadSnakeIdSet.delete(snakeId)
            if (!snakeSet.has(snakeId)) {
                //待加载的
                loadSnakes.push(snake)
                snakeSet.add(snakeId)
            }
        })
        unloadSnakeIdSet.forEach(snakeId => snakeSet.delete(snakeId))

        return { loadSnakes, unloadSnakeIdSet }
    }

}